/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.haiberg.osgi.bundle.reportservice.utils;

import com.haiberg.osgi.bundle.utils.FileUtils;
import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.MathContext;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 *
 * @author gyue
 */
public class Utils {

    public static SimpleDateFormat dateFormat_ddMMyyyyHHmmss = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
    public static SimpleDateFormat dateFormat_ddMMyyyyHHmm = new SimpleDateFormat("dd.MM.yyyy HH:mm");
    public static SimpleDateFormat dateFormat_ddMMyyyy = new SimpleDateFormat("dd.MM.yyyy");
    public static SimpleDateFormat dateFormat_ddMMyy = new SimpleDateFormat("dd.MM.yy");
    public static SimpleDateFormat dateFormat_ddMM = new SimpleDateFormat("dd.MM");
    public static SimpleDateFormat dateFormat_dd = new SimpleDateFormat("dd");
    public static SimpleDateFormat dateFormat_MM = new SimpleDateFormat("MM");
    public static SimpleDateFormat dateFormat_yyyy = new SimpleDateFormat("yyyy");
    public static SimpleDateFormat dateFormat_yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
    public static SimpleDateFormat dateFormat_wwyyyy = new SimpleDateFormat("ww/yyyy");
    public static SimpleDateFormat dateFormat_ddMMyyyy_HHmmss_noseperators = new SimpleDateFormat("ddMMyyyy_HHmmss");

    public static boolean equals(Collection collection1, Collection collection2) {
        if (collection1 == collection2) {
            return true;
        }
        if (collection1 == null || collection2 == null) {
            return false;
        }

        return (collection1.size() == collection2.size())
                && (collection1.containsAll(collection2));
    }

    public static boolean equals(Object object1, Object object2) {
//        return (object1 == object2) || ((object1 != null) && object1.equals(object2));

        return (object1 == null) ? (object2 == null) : object1.equals(object2);
    }

    public static String replaceString(String theSource, String oldSubstring, String newSubstring) {
        if (theSource == null || oldSubstring == null || newSubstring == null) {
            throw new NullPointerException("Utils.replaceString():: Null parameter(s) found: " + theSource + ", " + oldSubstring + ", " + newSubstring);
        }

        if (oldSubstring.equals("")) {
            throw new IllegalArgumentException("Utils.replaceString():: Cannot replace empty substring");
        }

        StringBuffer result = new StringBuffer();

        int pos;
        int len = oldSubstring.length();
        while ((pos = theSource.indexOf(oldSubstring)) > -1) {
            result.append(theSource.substring(0, pos)).append(newSubstring);
            theSource = theSource.substring(pos + len);
        }
        result.append(theSource.substring(0));
        return result.toString();
    }

    private static MathContext mc = new MathContext(0);

    public static BigDecimal getBigDecimal(String number) {
        try {
            number = number.replaceAll(",", ".");
            double doubleNumber = getDouble(number).doubleValue();

            return new BigDecimal(doubleNumber, mc);
        } catch (Exception e) {
            return null;
        }
    }

    public static BigDecimal getBigDecimal(int number) {
        try {
            return new BigDecimal(number, mc);
        } catch (Exception e) {
            return null;
        }
    }

    public static BigDecimal getBigDecimal(double number) {
        try {
            return new BigDecimal(number, mc);
        } catch (Exception e) {
            return null;
        }
    }

    public static BigDecimal getBigDecimal(Object number) {
        try {
            if (number instanceof Integer) {
                return new BigDecimal(((Integer) number).doubleValue());
            }
            if (number instanceof Double) {
                return new BigDecimal(((Double) number).doubleValue());
            }
        } catch (Exception e) {
            return null;
        }

        return null;
    }

    public static Integer getInt(String number) {
        try {
            return new Integer(number);
        } catch (Exception e) {
            return null;
        }

    }

    public static boolean isFloat(String number) {
        try {
            new Float(number);
        } catch (Exception e) {
            return false;
        }
        return true;

    }

    public static boolean isDouble(String number) {
        try {
            new Double(number);
        } catch (Exception e) {
            return false;
        }
        return true;

    }

    public static boolean isLong(String number) {
        try {
            new Long(number);
        } catch (Exception e) {
            return false;
        }
        return true;

    }

    public static boolean isInteger(String number) {
        try {
            new Integer(number);
        } catch (Exception e) {
            return false;
        }
        return true;

    }

    public static boolean notEmpty(String field) {
        return (field != null) && (field.length() > 0);
    }

    public static boolean notEmptyAndMinLen(String field, int minLength) {
        return (field != null) && (field.length() >= minLength);
    }

    public static Long getLong(String string) {
        try {
            return new Long(string);
        } catch (Exception e) {
            return null;
        }
    }

    public static Long getLong(int value) {
        try {
            return new Long(value);
        } catch (Exception e) {
            return null;
        }
    }

    public static Integer getInteger(String string) {
        try {
            return new Integer(string);
        } catch (Exception e) {
            return null;
        }
    }

    public static Float getFloat(String string) {
        try {
            return new Float(string);
        } catch (Exception e) {
            return null;
        }
    }

    public static Double getDouble(String string) {
        try {
            return new Double(string);
        } catch (Exception e) {
            return null;
        }
    }

    public static String getObjectStateAsValue(int theIntValue) {
        StringBuffer result = new StringBuffer();

        result.append("[");
        result.append(theIntValue);
        result.append("]");

        return result.toString();
    }

    public static String getObjectStateAsValue(boolean theBooleanValue) {
        StringBuffer result = new StringBuffer();

        result.append("[");
        result.append(theBooleanValue);
        result.append("]");

        return result.toString();
    }

    public static String getObjectStateAsValue(Object theObject) {
        StringBuffer result = new StringBuffer();

        result.append("[");
        result.append((theObject != null ? theObject.toString() : ""));
        result.append("]");

        return result.toString();
    }

    public static String getCollectionStateAsValues(Collection theCollection) {
        StringBuffer result = new StringBuffer();

        result.append("[");

        if (theCollection != null) {
            int i = 0;
            for (Iterator it = theCollection.iterator(); it.hasNext(); i++) {
                if (i > 0) {
                    result.append(", ");
                }

                result.append(it.next().toString());
            }
        }

        result.append("]");

        return result.toString();
    }

    public static List getAttributesWithDelim(String string, String delim) {
        try {
            List resultList = new ArrayList();

            int posStart = 0;
            int posEnd = string.indexOf(delim);

            while (posEnd != -1 && posStart != -1 && posEnd >= posStart) {
                if (string.length() >= posEnd) {
                    String res = string.substring(posStart, posEnd);
                    resultList.add(res);
                }

                posStart = string.indexOf(delim, posEnd) + 7;
                posEnd = string.indexOf(delim, posStart);
            }

            return resultList;
        } catch (Exception e) {
            return null;
        }

    }

    public static String createSearchStringWithLower(String searchString) {
        StringBuffer parameter = new StringBuffer();
        try {
//			int index1=0;
//			int index2=0;
//			String subString=null;
//			
//			index1=searchString.indexOf("\"");
//			if(index1!=-1) {
//				index2=searchString.indexOf("\"", index1+1);
//				
//			}

            // Variante 1
            // dies ist nur eine vorlaeufige Version. Es wird nur anhand von ',' gesplitet
            // da aber das Komma auch in den Namen vorkommen kann muss es nochmal ueberarbeitet werden
            //String[] strings = searchString.split(",");
            // Variante 
            Object[] strings = split(searchString);
            parameter.append("lower('" + ((String) strings[0]).replace('"', ' ').trim() + "')");
            for (int i = 1; i < strings.length; i++) {
//				aList.add(strings[i]);
                parameter.append(",lower('" + ((String) strings[i]).replace('"', ' ').trim() + "')");
            }

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        return parameter.toString();
    }

    // test 
    private static Object[] split(String searchString) {
        boolean ap = false;
        int index = 0;
        List list = new ArrayList();

        searchString = searchString.replace(",,", ",");

        for (int i = 0; i < searchString.length(); i++) {
            if (searchString.charAt(i) == ',') {
                if (!ap) {
                    list.add(searchString.substring(index, i));
                    index = i + 1;
                }
            }
            if (searchString.charAt(i) == '"') {
                ap = !ap;
            }
        }
        list.add(searchString.substring(index, searchString.length()));

        return list.toArray();
    }

    public static boolean isDate_ddmmyyy(String date_str, SimpleDateFormat df) {
        try {
            df.parse(date_str);
            return true;
        } catch (Exception e) {
        }
        return false;
    }

    public static Date getDateOrDateTime(String paramValue) {
        Date theDate = null;

        if (theDate == null) {
            try {
                theDate = dateFormat_ddMMyyyyHHmmss.parse(paramValue);
            } catch (Exception e) {
            }
        }

        if (theDate == null) {
            try {
                theDate = dateFormat_ddMMyyyyHHmm.parse(paramValue);
            } catch (Exception e) {
            }
        }

        if (theDate == null) {
            try {
                theDate = dateFormat_ddMMyyyy.parse(paramValue);
            } catch (Exception e) {
            }
        }

        if (theDate == null) {
            try {
                theDate = dateFormat_yyyyMMdd.parse(paramValue);
            } catch (Exception e) {
            }
        }

        if (theDate == null) {
            try {
                theDate = dateFormat_ddMMyy.parse(paramValue);
            } catch (Exception e) {
            }
        }

        if (theDate == null) {
            try {
                theDate = dateFormat_yyyy.parse(paramValue);
            } catch (Exception e) {
            }
        }

        if (theDate == null) {
            try {
                theDate = dateFormat_ddMM.parse(paramValue);
            } catch (Exception e) {
            }
        }

        return theDate;

    }

    public static Long getLongFromObj(Object resultObj) {
        Long result = null;
        try {

            if (resultObj instanceof Long) {
                result = (Long) resultObj;
            } else if (resultObj instanceof Integer) {
                result = new Long(((Integer) resultObj).longValue());
            }

            if (result == null) {
                result = getLong("" + resultObj);
            }

        } catch (Exception e) {
        }

        return result;
    }

    public static String getDateStringByPattern(String dateFormat_pattern) {
        try {
            SimpleDateFormat df = new SimpleDateFormat(dateFormat_pattern);
            return df.format(new Date());
        } catch (Exception e) {
        }
        return "";
    }

    public static String getDateStringByPattern(Date theDate, String dateFormat_pattern) {
        try {
            SimpleDateFormat df = new SimpleDateFormat(dateFormat_pattern);
            return df.format(theDate);
        } catch (Exception e) {
        }
        return "";
    }

    public static String getWeekString(Date begin_date) {
        String res = "";
        try {
            if (begin_date != null) {
                res = dateFormat_wwyyyy.format(begin_date);
            }

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return res;
    }

//	public static String getPolicyRightsStateAsValues(Collection thePolicyRights)
//	{
//		StringBuffer result = new StringBuffer();
//
//		result.append("[");
//
//		if(thePolicyRights != null)
//		{
//			int i = 0;
//			for(Iterator it = thePolicyRights.iterator(); it.hasNext(); i++)
//			{
//				if(i > 0)
//				{
//					result.append(", ");
//				}
//
//				result.append(it.next().toString());
//			}
//		}
//
//		result.append("]");
//
//		return result.toString();
//	}
    public static int parseInt(String intString) {
        int ret = 0;

        try {
            if (intString != null && intString.length() > 0) {
                ret = Integer.parseInt(intString);
            } else {
                ret = 0;
            }
        } catch (Exception e) {
            ret = 0;
        }

        return ret;
    }

    public static Double getAsRoundedDouble(BigDecimal value, int roundDigits) {
        if (value == null) {
            return null;
        } else {
            return new Double(Math.round(value.doubleValue() * Math.pow(10, roundDigits)) / Math.pow(10, roundDigits));
        }
    }

    public static String hexEncode(byte[] aInput) {
        StringBuffer result = new StringBuffer();
        char[] digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        for (int idx = 0; idx < aInput.length; ++idx) {
            byte b = aInput[idx];
            result.append(digits[(b & 0xf0) >> 4]);
            result.append(digits[b & 0x0f]);
        }
        return result.toString();
    }

    public static String listToDelimString(List<?> theList,
            String delimitter) {
        return listToDelimString(theList, delimitter, "");
    }

    public static String listToDelimString(List<?> theList,
            String delimitter, String elementDecorator) {
        String result = "";
        if (theList != null) {
            int i = 0;
            for (Object object : theList) {
                if (i > 0) {
                    result += delimitter;
                }
                result += elementDecorator + object + elementDecorator;
                i++;
            }
        }
        return result;
    }

    public static int ToOleColor(java.awt.Color color) {
        return color.getRed() + color.getGreen() * 256
                + color.getBlue() * 256 * 256;
    }

    public static Color FromOleColor(int color) {
        int blueInt = color / (256 * 256);
        int greenInt = (color - (blueInt * (256 * 256))) / (256);
        int redInt = color - (blueInt * (256 * 256)) - (greenInt * 256);

        return new Color(redInt, greenInt, blueInt);
    }

    public static String FromOleToHex(int fillColor) {
        String hexColor = "#000000";
        try {
            int blueInt = fillColor / (256 * 256);
            int greenInt = (fillColor - (blueInt * (256 * 256))) / (256);
            int redInt = fillColor - (blueInt * (256 * 256)) - (greenInt * 256);
            String red = Integer.toHexString(redInt);
            red += red.length() < 2 ? "0" : "";
            String green = Integer.toHexString(greenInt);
            green += green.length() < 2 ? "0" : "";
            String blue = Integer.toHexString(blueInt);
            blue += blue.length() < 2 ? "0" : "";

            hexColor = "#" + red + "" + green + "" + blue;
        } catch (Exception e) {
        }
        return hexColor;
    }

    public static Color FromHexToColor(String hexColor) {
        if (hexColor != null && hexColor.length() > 0) {
            try {
                int intValue = Integer.parseInt(hexColor.replaceAll("\\#", "").trim(), 16);
                Color aColor = new Color(intValue);
                return aColor;
            } catch (Exception e) {
            }
            return null;

        }
        return null;
    }

    public static String FromColorToHex(Color theColor) {
        String hexColor = "#000000";
        try {
            int blueInt = theColor.getBlue();
            int greenInt = theColor.getGreen();
            int redInt = theColor.getRed();
            String red = Integer.toHexString(redInt);
            red += red.length() < 2 ? "0" : "";
            String green = Integer.toHexString(greenInt);
            green += green.length() < 2 ? "0" : "";
            String blue = Integer.toHexString(blueInt);
            blue += blue.length() < 2 ? "0" : "";

            hexColor = "#" + red + "" + green + "" + blue;
        } catch (Exception e) {
        }
        return hexColor;
    }

    public static String generateSQLCondition(String pre, String geomCompositionFieldname, String operator, String criteria
    ) {
        String whereClause = "";

        if (criteria.length() > 0 && geomCompositionFieldname.length() > 0 && operator.length() > 0) {
            // Check If is Like  criteria
            if (operator.toLowerCase().indexOf("in") > -1) {
                // Split Criteria if comma seperated
                String[] criteriaSplits = criteria.split(",");
                if (criteriaSplits != null) {
                    // Build criteria String
                    criteria = "(";
                    for (int i = 0; i < criteriaSplits.length; i++) {
                        if (i > 0) {
                            criteria += ",";
                        }

                        if (geomCompositionFieldname.startsWith("string") || geomCompositionFieldname.startsWith("date") || geomCompositionFieldname.startsWith("text") || geomCompositionFieldname.startsWith("name")) {
                            criteria += "'" + criteriaSplits[i].replaceAll("\\A *", "") + "'";
                        } else {
                            criteria += criteriaSplits[i];
                        }

                    }
                    criteria += ")";
                }
            } else {
                if (geomCompositionFieldname.startsWith("string") || geomCompositionFieldname.startsWith("date") || geomCompositionFieldname.startsWith("text") || geomCompositionFieldname.startsWith("name") || !Utils.isDouble(criteria)) {
                    criteria = "'" + criteria + "'";
                    if (!(geomCompositionFieldname.startsWith("string") || geomCompositionFieldname.startsWith("date") || geomCompositionFieldname.startsWith("text") || geomCompositionFieldname.startsWith("name"))) {
                        geomCompositionFieldname = " cast( " + geomCompositionFieldname + " as text ) ";
                        pre = "";
                    }
                }
            }

            if (operator.toLowerCase().indexOf("like") > -1
                    && !((geomCompositionFieldname.startsWith("string") || geomCompositionFieldname.startsWith("date") || geomCompositionFieldname.startsWith("text") || geomCompositionFieldname.startsWith("name")))) {
                if (Utils.isDouble(criteria)) {
                    operator = "=";
                } else {
                    geomCompositionFieldname = "cast(" + geomCompositionFieldname + " as text)";
                }
            }

            whereClause += pre + geomCompositionFieldname + " " + operator + " " + criteria;
        }
        return whereClause;
    }

    public static Boolean getBoolean(String lastValueX) {
        try {
            if ("t".equalsIgnoreCase(lastValueX) || "true".equalsIgnoreCase(lastValueX) || "1".equalsIgnoreCase(lastValueX) || "yes".equalsIgnoreCase(lastValueX) || "ja".equalsIgnoreCase(lastValueX)) {
                return true;
            } else if ("f".equalsIgnoreCase(lastValueX) || "false".equalsIgnoreCase(lastValueX) || "0".equalsIgnoreCase(lastValueX) || "no".equalsIgnoreCase(lastValueX) || "nein".equalsIgnoreCase(lastValueX)) {
                return false;
            } else {
                return new Boolean(lastValueX);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getMD5Hash(String userpass) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] data = md.digest(userpass.getBytes("CP1252"));
            return getHex(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String getHex(byte[] array) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < array.length; ++i) {
            sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).toUpperCase().substring(1, 3));
        }
        return sb.toString();
    }

    public static void extractZip(String srcFile, String desFolder)
            throws Exception {
        File destFolder = new File(desFolder);
        destFolder.mkdirs();

        String destinationname = desFolder;
        byte[] buf = new byte[1024];
        ZipInputStream zipinputstream = null;
        ZipEntry zipentry;
        zipinputstream = new ZipInputStream(
                new FileInputStream(srcFile));

        zipentry = zipinputstream.getNextEntry();
        while (zipentry != null) {
            //for each entry to be extracted
            String entryName = zipentry.getName();
            int n;
            FileOutputStream fileoutputstream;
            File newFile = new File(entryName);
            String directory = newFile.getParent();

            if (directory == null) {
                if (newFile.isDirectory()) {
                    break;
                }
            }

            fileoutputstream = new FileOutputStream(
                    destinationname + entryName);

            while ((n = zipinputstream.read(buf, 0, 1024)) > -1) {
                fileoutputstream.write(buf, 0, n);
            }

            fileoutputstream.close();
            zipinputstream.closeEntry();
            zipentry = zipinputstream.getNextEntry();

        }//while

        zipinputstream.close();

    }

    public static String generateCQLCondition(String pre,
            String geomCompositionFieldname, String operator, String criteria) {
        String whereClause = "";

        if (criteria.length() > 0 && geomCompositionFieldname.length() > 0 && operator.length() > 0) {
            // Check If is Like  criteria
            if (operator.toLowerCase().indexOf("in") > -1) {
                // Split Criteria if comma seperated
                String[] criteriaSplits = criteria.split(",");
                if (criteriaSplits != null) {
                    // Build criteria String
                    whereClause = "(";
                    for (int i = 0; i < criteriaSplits.length; i++) {
                        if (!Utils.isLong(criteria)) {
                            criteria = "'" + criteriaSplits[i].replaceAll("\\A *", "") + "'";
                        } else {
                            criteria = criteriaSplits[i];
                        }

                        whereClause += (i > 0 ? " OR " : "") + pre + geomCompositionFieldname + " = " + criteria;

                    }
                    whereClause += ")";
                }

                if (operator.toLowerCase().indexOf("not") > -1 && whereClause.length() > 0) {
                    whereClause = "NOT " + whereClause;
                }
            } else {
                if (!Utils.isLong(criteria)) {
                    criteria = "'" + criteria + "'";
                }
                whereClause += pre + geomCompositionFieldname + " " + operator + " " + criteria;
            }

        }
        return whereClause;
    }

    public static String replaceBadCharactersFromFieldName(String name) {
        String replacename = "" + name;

        return replacename.replaceAll("\\.", "_").replaceAll("!", "_").replaceAll(" ", "_").
                replaceAll("!", "_").replaceAll("'", "_").replaceAll("\"", "_").replaceAll("%", "_")
                .replaceAll("/", "_").replaceAll(",", "_").replaceAll("\\$", "_").replaceAll("�", "_")
                .replaceAll("&", "_").replaceAll("\\(", "_").replaceAll("\\)", "_").replaceAll("\\?", "_")
                .replaceAll("=", "_").replaceAll("�", "_").replaceAll("`", "_").replaceAll("\\*", "_")
                .replaceAll("\\+", "_").replaceAll("\\-", "_").replaceAll("#", "_").replaceAll(":", "_")
                .replaceAll(";", "_").replaceAll("<", "_").replaceAll(">", "_").replaceAll("\\|", "_")
                .replaceAll("�", "Ue").replaceAll("�", "ue")
                .replaceAll("�", "Ae").replaceAll("�", "ae")
                .replaceAll("�", "Oe").replaceAll("�", "oe")
                .replaceAll("�", "ss");

    }

    /**
     * getting system root path for project classpath
     *
     * @param resoucesName
     * @return
     */
    @Deprecated
    public static String getRootPath(String... resoucesPath) {

        String resoucesPathStr = resoucesPath.length == 0 ? "" : resoucesPath[0];
        String path = FileUtils.class.getClassLoader().getResource(resoucesPathStr).getPath();

        try {
            return URLDecoder.decode(path, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            
        }
        return null;
    }
}
